<?php

namespace app\common\model;

use addons\epay\library\Service;
use app\common\library\Auth;
use app\common\model\order\Rescue;
use think\Db;
use think\Exception;
use think\Log;
use think\Model;
use think\Request;
use traits\model\SoftDelete;

class Pay extends Model
{
    use SoftDelete;

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';
    // 追加属性
    protected $append = [
        'pay_state_text',
        'pay_type_text',
        'paymenttime_text',
    ];

    public function getPayStateList(){
        return ['10'=>'未支付','20'=>'已支付','30'=>'部分退款','40'=>'全部退款'];
    }

    public function getPayTypeList()
    {
        return ['10' => __('微信支付'), '20' => __('支付宝支付')];
    }

    public function getPayTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_type']) ? $data['pay_type'] : '');
        $list = $this->getPayTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getPayStateTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_state']) ? $data['pay_state'] : '');
        $list = $this->getPayStateList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getPaymenttimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['paymenttime']) ? $data['paymenttime'] : '');
        return (!is_string($value)) ? date('Y-m-d H:i:s',$value) : '';
    }

    private function  setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    public function hasError()
    {
        return !empty($this->error);
    }

    /**
     * 创建支付数据，并发起申请
     * @param $user_id          会员id
     * @param $resourceType     资源类型  1：商家入驻    2： 技工入驻  3: 援助完成后用户支付 4：援助订单有责取消
     * @param $order_id        商城 资源类型对应ID
     * @param $type             支付类型:wechat=微信支付,alipay=支付宝支付
     * @param $notifyapi        回调接口，无需带域名
     * @param $returnurl        跳转返回URL
     * @param $body             描述，下单
     * @param $method           支付方法  web、wap、app、scan、pos、mp，miniapp
     * @param $openid           用户在直连商户appid下的唯一标识
     * @return false|mixed
     * @throws \Exception
     */
    public function createPay($user_id,$resourceType,$order_id, $type, $notifyapi, $returnurl,$body='下单', $method='app',$openid=null){
        if(empty($resourceType)){
            $this->setError('参数resourceType缺失');
            return false;
        }
        if(empty($order_id)){
            $this->setError('参数order_id缺失');
            return false;
        }
        $pay_no = date('YmdHis').rand(1000,9999);
        if(($type != 'wechat') && ($type != 'alipay')){
            $this->setError('支付类型错误');
            return false;
        }
        $payData = [
            'user_id' => $user_id,
            'pay_type' => $type,
            'pay_no' => $pay_no,
        ];
        switch (intval($resourceType)){
            case 1:    // 商家入驻
                $model = new Store();
                // 未审核、未支付的商家申请
                $storeInfo = $model->where(['id'=>['=',$order_id],'pay_status' => ['=','10'],'user_id'=>['=',$user_id],'pay_way'=>['<>','30'],'amount'=>['>',0],'state'=>['=','10']])->find();
                if(empty($storeInfo)){
                    $this->setError('商家入驻错误');
                    return false;
                }
                $payData['store_id'] = $order_id;
                $payData['amount'] = $storeInfo->amount;
                break;
            case 2:    // 技工入驻
                $model = new Artificer();
                // 未审核、未支付的商家申请
                $artificerInfo = $model->where(['id'=>['=',$order_id],'pay_status' => ['=','10'],'user_id'=>['=',$user_id],'pay_way'=>['<>','30'],'amount'=>['>',0],'state'=>['=','10']])->find();
                if(empty($artificerInfo)){
                    $this->setError('技工入驻错误');
                    return false;
                }
                $payData['artificer_id'] = $order_id;
                $payData['amount'] = $artificerInfo->amount;
                break;
            case 3:    // 援助完成后用户支付
                $model = new Rescue();
                // 进行中，技工援助完成
                $rescueInfo = $model->where(['id'=>['=',$order_id],'pay_status' => ['=','10'],'user_id'=>['=',$user_id],'pay_way'=>['<>','30'],'total_price'=>['>',0],'order_status'=>['=','10'],'aid_status'=>['=','20']])->find();
                if(empty($rescueInfo)){
                    $this->setError('援助订单错误');
                    return false;
                }
                $payData['rescue_order_id'] = $order_id;
                $payData['amount'] = $rescueInfo->total_price;
                break;
            case 4:    // 援助订单有责取消
                $model = new Rescue();
                // 进行中，技工已接单
                $rescueInfo = $model->where(['id'=>['=',$order_id],'pay_status' => ['=','10'],'user_id'=>['=',$user_id],'pay_way'=>['<>','30'],'order_status'=>['=','10'],'take_status'=>['=','20']])->find();
                if(empty($rescueInfo)){
                    $this->setError('援助订单错误');
                    return false;
                }
                $payData['rescue_order_id'] = $order_id;
                // 获取有责取消订单的后台设置
                $payData['amount'] = \app\common\model\Config::getValue('duty_cancel_order','user');
                break;
            default:
                $this->setError('参数resourceType错误');
                return false;
        }
        //测试
        $amount = 0.01;

        $pay = self::create($payData,true);
        if($pay->id){
            //测试
            return $pay_no;
            $data = Service::submitOrder([
                'amount' => $amount,
                'orderid' => $pay_no,
                'type' => $type,
                'title' => $body,
                'notifyurl' => Request::instance()->domain().'/'.$notifyapi,
                'returnurl' => $returnurl,
                'method' => $method,
            ]);
            $data = ($type == 'wechat') ? json_decode($data,true) : $data;
            return $data;
        }else{
            $this->setError('支付数据失败');
            return false;
        }
    }

    public function notify($pay_no,$transaction_id){
        Db::startTrans();
        try {
            $payData = self::where(['pay_no'=>['=',$pay_no]])->lock(true)->find();
            if(empty($payData)){
                return  false;
            }
            //商家入驻
            if($payData->store_id){
                $order = Store::where(['id'=>['=',$payData->store_id],'pay_status'=>['=','10'],'state' => ['=','10']])->find();
                if (empty($order)) { // 如果订单不存在
                    throw new Exception('商家入驻不存在');
                }
                //改变订单状态，
                $order->pay_status = '20';
                $order->paytime = time();
                $order->transaction_id = $transaction_id;
                $order->save();
            }
            //技工入驻
            if($payData->artificer_id){
                $artificer = Artificer::where(['id'=>['=',$payData->artificer_id],'pay_status'=>['=','10'],'state' => ['=','10']])->find();
                if (empty($artificer)) { // 如果订单不存在
                    throw new Exception('技工入驻不存在');
                }
                //改变订单状态，
                $artificer->pay_status = '20';
                $artificer->paytime = time();
                $artificer->transaction_id = $transaction_id;
                $artificer->save();
            }
            // 技工完成援助客户支付；客户有责取消援助订单
            if($payData->rescue_order_id){
                $rescue = Rescue::where(['id'=>['=',$payData->rescue_order_id],'pay_status'=>['=','10'],'order_status' => ['=','10']])->find();
                if (empty($rescue)) { // 如果订单不存在
                    throw new Exception('援助订单不存在');
                }
                //改变订单状态，
                if($rescue->duty_status == '20'){
                    //客户有责援助
                    $rescue->order_status = '30';
                    $rescue->canceltime = time();
                }else{
                    $rescue->order_status = '20';
                }
                $rescue->pay_status = '20';
                $rescue->paytime = time();
                $rescue->transaction_id = $transaction_id;
                $rescue->pay_price = $payData->amount;
                $rescue->allowField(true)->save();
            }
            $payData->paymenttime = time();
            $payData->pay_state = '20';
            $payData->trade_no = $transaction_id;
            $payData->save();
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            Log::write('回调失败：'.$e->getMessage(),'error',true);
            return false;
        }
    }

    /**
     * 查询支付状态
     * @param $user_id
     * @param $order_ids
     * @return void
     */
    public function inquireStatusBuyOrderId($order_ids){
        try {
            $payInfo = self::where(['order_ids'=>['=',$order_ids]])->order('id desc')->find();
            if(empty($payInfo)){
                $this->setError('参数order_id错误');
                return false;
            }
            // 支付类型:wechat=微信支付,alipay=支付宝支付
            $type = $payInfo['pay_type'];
            //Log::write('配置项：'.var_export(Service::getConfig($type),true),'log',true);
            if($type === 'wechat'){
                $tempPay = \Yansongda\Pay\Pay::wechat(Service::getConfig($type));
                $order = [
                    'transaction_id' => $payInfo['trade_no'],
                ];
            }else{
                $tempPay = \Yansongda\Pay\Pay::alipay(Service::getConfig($type));
                //系统内部订单号
                $order = [
                    'out_trade_no' => $payInfo['pay_no'],
                ];
            }
            $data = $tempPay->find($order);
            return $data;
        }catch (Exception $e){

        }
    }
}